const logger = require('../utils/console-logger.js')
const Model = require('../models/sub-model')
const ResponseModel = require('../models/response-model')

const LibraryService = require('../services/library-service')
const SubService = require('../services/sub-service')
const MediaService = require('../services/media-service')
const Jellyfin = require('../utils/media-server/jellyfin-server');

const SubFunc = require('../core/SubFunc')



module.exports = {

    // 查询
    'get::/sub/list': async function(ctx) {
        const params = ctx.request.query

        const { keyword , mediaType } = params

        const whereBuilder = modelQuery => {
            if (keyword) {
                modelQuery.where(function () {
                    this.where('title', 'like', `%${keyword}%`)
                })
            }
            if (mediaType) {
                modelQuery.where(function () {
                    this.where('media_type', mediaType)
                })
            }
        }
        const columns = ['id', 'addtime', 'title', 'year', 'media_type', 'status', 'tmdbid', 'info', 'libraryid']
        const page = await Model.page(Model.buildPaging(params), whereBuilder, columns)

        ctx.response.body = ResponseModel.success(page)
    },
    // 订阅
    'post::/sub/do': async function(ctx) {
        const { tmdbid, type, seasons } = ctx.request.body

        console.log('tmdbid:', tmdbid, 'type:', type, 'seasons:', seasons);
        if (tmdbid && type) {
            let sub = await Model.getByTmdbid(tmdbid)
            let media = await MediaService.getMedia(tmdbid, type)
            if (media) {
                const info = JSON.parse(media.info)
                if (type === 'tv' && seasons && seasons.length) {
                    const toSubSeasons = [];
                    for (let index = 0; index < info.seasons.length; index++) {
                        const season = info.seasons[index];
                        if (seasons.includes(season.season_number)) {
                            const mediaSeason = await MediaService.getMediaSeason(tmdbid, season.season_number)
                            if (mediaSeason) {
                                const seasonInfo = JSON.parse(mediaSeason.info)
                                const allEpisodes = seasonInfo.episodes.map(episode => episode.episode_number)
                                const existsEpisodes = await Jellyfin.getTvEpisodes(info.title, undefined, season.season_number)
                                const no_exists_episodes = allEpisodes.filter(episode => !existsEpisodes.includes(episode))
                                toSubSeasons.push({
                                    episode_count: allEpisodes.length,
                                    season_number: season.season_number,
                                    exists: existsEpisodes,
                                    lack: no_exists_episodes
                                })
                            }
                        }   
                    }
                
                    if (!sub) {
                        const libraryid = await LibraryService.guessLibrary({
                            mediaType: 'tv', 
                            genre_ids: info.genres.map(genre => genre.id), 
                            original_language: info.original_language, 
                            origin_country: info.origin_country,
                        })
                        sub = {
                            addtime: new Date(),
                            tmdbid: media.tmdbid,
                            mediaType: media.type,
                            libraryid: libraryid,
                            title: info.title,
                            year: info.year,
                            status: 'sub',
                            seasons: JSON.stringify(toSubSeasons),
                            info: JSON.stringify({
                                poster: info.poster,
                                original_name: info.original_name,
                            })
                        }
                        await Model.insert(sub)
                    } else {
                        // 合并已订阅
                        const subSeasons = JSON.parse(sub.seasons)
                        for (let index = 0; index < toSubSeasons.length; index++) {
                            const toSubSeason = toSubSeasons[index];
                            const subSeason = subSeasons.find(season => season.season_number === toSubSeason.season_number)
                            if (subSeason) { 
                                subSeason.episode_count = toSubSeason.episode_count
                                subSeason.exists = toSubSeason.exists
                                subSeason.lack = toSubSeason.lack
                            } else {
                                subSeasons.push(toSubSeason)
                            }
                        }
                        await Model.updateBy({seasons: JSON.stringify(subSeasons)}, {id: sub.id})
                    }
                } else if (type === 'movie' ) {
                    const exists = await Jellyfin.getMovie(info.title, info.year.split('-')[0])
                    if (!sub) {
                        const libraryid = await LibraryService.guessLibrary({
                            mediaType: 'movie', 
                            genre_ids: info.genres.map(genre => genre.id), 
                            original_language: info.original_language, 
                            origin_country: info.origin_country,
                        })
                        sub = {
                            addtime: new Date(),
                            tmdbid: media.tmdbid,
                            mediaType: media.type,
                            libraryid: libraryid,
                            title: info.title,
                            year: info.year,
                            status: exists ? 'playable' : 'sub',
                            info: JSON.stringify({
                                poster: info.poster,
                                original_name: info.original_name,
                            })
                        }
                        await Model.insert(sub)
                    } else {
                        await Model.updateBy({status: exists ? 'playable' : 'sub'}, {id: sub.id})
                    }
                }
            }
        }

        ctx.response.body = ResponseModel.success()
    },
    // 更新部分属性
    'post::/sub/update': async function (ctx) {

        const { id, order, libraryid, search } = ctx.request.body

        if (id) {
            const updateModel = {}
            if (!isNaN(order)) {
                updateModel.order = order
            }
            if (libraryid) {
                updateModel.libraryid = libraryid
            }
            if (search) {
                updateModel.search = search
            }
            const updated = await Model.updateBy(updateModel, { id: id })
        }
        ctx.response.body = ResponseModel.success()
    },
    // 获取sub信息
    'get::/sub/find/:id': async function (ctx) {
        const { id } = ctx.request.params
        const model = await Model.getById(id)
        ctx.response.body = ResponseModel.success(model)
    },
    // 获取详情含TMDB信息
    'get::/sub/getDetail': async function(ctx) {
        const { tmdbid, type } = ctx.request.query
        let data = {}
        if (tmdbid && type) {
            const sub = await Model.getByTmdbid(tmdbid)
            const media = await MediaService.getMedia(tmdbid, type);
            data = {
                tmdbid: media.tmdbid,
                ...JSON.parse(media.info),
                subId: sub?.id,
                subStatus: sub?.status,
                subLibraryid: sub?.libraryid,
                subSeasons: [],
            }
            if (sub?.seasons && sub?.seasons.length) {
                const subSeasons = JSON.parse(sub.seasons)
                for (let index = 0; index < subSeasons.length; index++) {
                    const subSeason = subSeasons[index];
                    const mediaSeason = await MediaService.getMediaSeason(tmdbid, subSeason.season_number)
                    if (mediaSeason) {
                        subSeason.episodes =  JSON.parse(mediaSeason.info).episodes
                        data.subSeasons.push(subSeason)
                    }
                }
            }
            delete data.id // 避免与 tmdbid 冲突
        }
        ctx.response.body = ResponseModel.success(data)
    },
    // 获取季信息
    'get::/sub/getSeasons': async function(ctx) {
        const { tmdbid, seasons } = ctx.request.query
        let data = []
        if (tmdbid && seasons && seasons.length) {
            Promise.all(seasons.map(async season => await MediaService.getMediaSeason(tmdbid, season))).then(res => {
                data = res
            })
        }
        ctx.response.body = ResponseModel.success(data)
    },
    // 删除
    'get::/sub/delete/:id': async function(ctx) {

        const { id } = ctx.request.params
        if (id) {
            const model = await Model.getById(id)
            if (model) { 
                const deleted = await Model.delete({ id: id })
                await MediaService.deleteMedia(model.tmdbid)
            }
        }
        ctx.response.body = ResponseModel.success()
    },
    // 订阅处理
    'get::/sub/action': async function(ctx) {
        const { id } = ctx.request.query
        let logs = ''
        if (id) {
            let sub = await Model.getById(id)
            await logger.startRecord()
            // 更新TMDB媒体信息 !!! 目前只有手动更新单个订阅才刷新TMDB信息
            await SubService.updateMediaInfo([sub])
            // 同步媒体库
            await SubService.syncFromMediaServer([sub])
            // 查找订阅资源
            await SubFunc.prepare();
            sub = await Model.getById(id);
            await SubFunc.handelSub(sub)
            logs = await logger.shiftRecord()
        } else {
            SubFunc.action()
        }
        ctx.response.body = ResponseModel.success(logs)
    },
}
  